home *** CD-ROM | disk | FTP | other *** search
- name PrtScr
- title PrintScreen Impresión de pantalla selectiva
- subttl CopyRight (c) 1992 by Aitor Garay
-
- ScreenLenght equ (80d*25d*2d)
-
- code segment
- assume cs:code,ds:code,es:code,ss:code
- org 100h ; por ser de tipo COM
- Init: jmp Start
-
- PrtScrVector proc near ; rutina general de control
- cmp cs:State,1d ; comprobar si ya esta en memoria
- jnz StartCode
- iret ; ignorar segundas llamadas
- StartCode: mov cs:State,1d ; activar bandera
- cld ; para proceso de cadenas
- push ax ; salvar registros alterados
- push bx
- push cx
- push dx
- push si
- push di
- push es
- push ds
- mov ax,cs ; inicializar registros de segmento
- mov ds,ax
- mov es,ax
- mov ah,0fh ; obtener modo de video vía BIOS
- int 10h
- cmp al,02h ; comprobar modos procesables
- jz VideoOk
- cmp al,03h
- jz VideoOk
- cmp al,07h
- jz VideoOk
- mov ax,0e07h ; emitir pitido como señal de aviso
- int 10h
- CallLast: pushf ; simular una int 05h al vector anterior
- call dword ptr LastVector
- EndCode: pop ds
- pop es
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- mov cs:State,0d
- iret ; volver al codigo original
- VideoOk: mov ax,ScreenSeg ; actualizar valor del segmento de pantalla activo
- mov ScreenFSeg,ax
- mov ax,4096d ; calcular el OFFSET del la página activa
- mov cl,8d
- shr bx,cl
- mul bx
- add ScreenFSeg,ax
- call ScreenSave ; salvar contenido de la pantalla
- call MakeWindow ; dibujar el recuadro
- WaitUser: xor ah,ah
- int 16h ; esperar a alguna tecla
- cmp ax,1c0dh ; ¿ RETURN ?
- jnz NextKey00
- inc xCoord ; ajustar coordenadas
- inc yCoord
- dec x1Coord
- dec y1Coord
- call PrintCode ; llamar a codigo de impresión
- inc y1Coord
- inc x1Coord
- dec yCoord
- dec xCoord
- call ScreenRestore ; recuperar pantalla
- jmp EndCode ; salir
-
- NextKey00: cmp ax,3920h ; ¿ ESPACE ?
- jnz NextKey01
- call PrintCode
- call ScreenRestore
- jmp EndCode
-
- NextKey01: cmp ax,0e08h ; ¿ BACKSPACE ?
- jnz NextKey02
- call ScreenRestore
- jmp CallLast
-
- NextKey02: cmp ax,011bh ; ¿ ESCAPE ?
- jnz TestShift
- call ScreenRestore
- jmp EndCode
-
- TestShift: push ax ; guardar tecla obtenida
- mov ah,02h
- int 16h ; obtener marcas del teclado
- and al,00000011b ; comprobar marcas SHIFT
- pop ax
- jnz ShiftKey
- jmp NormalKey
-
- ShiftKey: cmp ax,4800h ; ¿ SHIFT-UP ?
- jnz NextKey03
- mov al,y1Coord ; comprobar rango
- dec al ; ajustar rango
- cmp al,yCoord
- jnz ShiftUpOk
- jmp WaitUser ; operación invalida
- ShiftUpOk: dec y1Coord
- jmp RedrawScreen ; regenerar la pantalla
-
- NextKey03: cmp ax,5000h ; ¿ SHIFT-DOWN ?
- jnz NextKey04
- cmp y1Coord,24d
- jnz ShiftDownOk
- jmp WaitUser
- ShiftDownOk: inc y1Coord
- jmp RedrawScreen
-
- NextKey04: cmp ax,4b00h ; ¿ SHIFT-LEFT ?
- jnz NextKey05
- mov al,x1Coord
- dec al
- cmp al,xCoord
- jnz ShiftLeftOk
- jmp WaitUser
- ShiftLeftOk: dec x1Coord
- jmp RedrawScreen
-
- NextKey05: cmp ax,4d00h ; ¿ SHIFT-RIGHT ?
- jnz UndefShiftKey
- cmp x1Coord,79d
- jnz ShiftRightOk
- UndefShiftKey: jmp WaitUser ; volver a leer tecla
- ShiftRightOk: inc x1Coord
- jmp RedrawScreen
-
- NormalKey: cmp ax,4800h ; ¿ UP ?
- jnz NextKey06
- cmp yCoord,0d ; comprobar rango
- jnz UpOk
- mov ax,4800h ; simula un SHIFT-UP
- jmp ShiftKey ; saltar para reproceso
- UpOk: dec yCoord
- dec y1Coord
- jmp RedrawScreen
-
- NextKey06: cmp ax,5000h ; ¿ DOWN ?
- jnz NextKey07
- cmp y1Coord,24d
- jnz DownOk
- cmp Recursive,1d ; comprobar modo recursivo
- jnz NextDown
- mov Recursive,0d
- jmp WaitUser
- NextDown: mov ah,05h
- mov cx,5000h ; simula un DOWN
- int 16h
- mov ax,4800h ; simula un SHIFT-UP
- mov Recursive,1d ; activar modo recursivo
- jmp ShiftKey
- DownOk: inc yCoord
- inc y1Coord
- mov Recursive,0d ; desactivar modo recursivo
- jmp RedrawScreen
-
- NextKey07: cmp ax,4b00h ; ¿ LEFT ?
- jnz NextKey08
- cmp xCoord,0d
- jnz LeftOk
- mov ax,4b00h ; simula un SHITF-LEFT
- jmp ShiftKey
- LeftOk: dec xCoord
- dec x1Coord
- jmp RedrawScreen
-
- NextKey08: cmp ax,4d00h ; ¿ RIGHT ?
- jnz NextKey09
- cmp x1Coord,79d
- jnz RightOk
- cmp Recursive,1d ; comprobar si estoy en modo recursivo
- jnz NextRight
- mov Recursive,0d ; ya no lo estoy
- jmp WaitUser ; esperar siguiente tecla
- NextRight: mov ah,05h
- mov cx,4d00h ; simula un RIGHT
- int 16h
- mov ax,4b00h ; simula un SHIFT-LEFT
- mov Recursive,1d ; activar modo recursivo
- jmp ShiftKey
- RightOk: inc xCoord
- inc x1Coord
- mov Recursive,0d ; desactivar modo recursivo
- jmp RedrawScreen
-
- NextKey09: cmp ax,4838h ; ¿ 8 ?
- jnz NextKey10
- mov ax,4800h ; simula un SHIFT-UP
- jmp ShiftKey
-
- NextKey10: cmp ax,4d36h ; ¿ 6 ?
- jnz NextKey11
- mov ax,4d00h ; simula un SHIFT-RIGHT
- jmp ShiftKey
-
- NextKey11: cmp ax,4b34h ; ¿ 4 ?
- jnz NextKey12
- mov ax,4b00h ; simula un SHIFT-LEFT
- jmp ShiftKey
-
- NextKey12: cmp ax,5032h ; ¿ 2 ?
- jnz UndefKey
- mov ax,5000h ; simula un SHIFT-DOWN
- jmp ShiftKey
-
- UndefKey: jmp WaitUser
-
- RedrawScreen: call ScreenRestore
- call MakeWindow
- jmp WaitUser
- PrtScrVector endp
-
- GotoXY proc near ; mueve DI a coordenadas X,Y (ah,al)
- mov di,ax ; la formula utilizada es :
- mov bl,160d ; OFFSET = Y*160 + X*2
- mul bl
- xchg di,ax
- mov cl,8d
- shr ax,cl
- shl ax,1d
- add di,ax
- ret
- GotoXY endp
-
- MakeWindow proc near
- push es
- mov es,ScreenFSeg ; semgneto de pantalla definitivo
- xor cx,cx ; para ahorrar codigo mas tarde
- mov ah,xCoord ; coordenadas ininicales
- mov al,yCoord
- call GotoXY
- mov ax,00FDAh ; caracter '┌'
- stosw
- call DrawLine ; dibujar linea horizontal
- mov ax,00FBFh ; caracter '┐'
- stosw
- mov cl,y1Coord ; calcular longitud de la linea vertical
- sub cl,yCoord
- dec cl
- jz NoVertLine ; no hay linea vectical
- mov dh,xCoord ; para ahorrar tiempo
- mov dl,x1Coord
- mov bh,yCoord
- DrawNext: push cx ; salvar contador general del bucle
- mov ah,dh
- mov al,bh
- add al,cl ; dibuja de abajo para arriba
- push ax ; para ser utilizado mas tarde
- call GotoXY
- mov ax,00FB3h ; caracter '│'
- stosw
- pop ax
- mov ah,dl
- call GotoXY
- mov ax,00FB3h ; caracter '│'
- stosw
- pop cx
- loop DrawNext
- NoVertLine: mov ah,xCoord
- mov al,y1Coord
- call GotoXY
- mov ax,00FC0h ; caracter '└'
- stosw
- call DrawLine
- mov ax,00FD9h ; caracter '┘'
- stosw
- pop es ; antes de salir recuperar ES
- ret
- DrawLine label near ; no merece crean una rutina aparte
- mov cl,x1Coord ; calcular tamaño en horizontal
- sub cl,xCoord
- dec cl ; ajustarlo
- mov ax,00FC4h ; caracter '─'
- rep stosw
- ret
- MakeWindow endp
-
- ScreenSave proc near ; salva el contenido de la pantalla
- push ds
- mov ds,ScreenFSeg
- xor si,si
- mov di,offset ScreenBuffer
- mov cx,ScreenLenght/2
- rep movsw
- pop ds
- ret
- ScreenSave endp
-
- ScreenRestore proc near ; recupera la pantalla del buffer
- push es
- mov es,ScreenFSeg
- xor di,di
- mov si,offset ScreenBuffer
- mov cx,ScreenLenght/2
- rep movsw
- pop es
- ret
- ScreenRestore endp
-
- PrintCode proc near ; rutina de impresión
- push es
- mov es,ScreenFSeg
- xor ch,ch ; parte alta de CX siempre a cero
- mov cl,x1Coord ; calcular numero de columnas
- sub cl,xCoord
- inc cl
- mov NumColum,cl ; guardar numero de columnas
- mov cl,y1Coord ; calcular numero de lineas
- sub cl,yCoord
- cmp cl,0d ; comprobar numero de lineas nulo
- jl PrintExit
- inc cl ; CL = numero de lineas a imprimir
- mov al,yCoord ; inicializar linea actual
- mov CurrentLine,al
- NextLine: push cx
- mov ah,xCoord
- mov al,CurrentLine
- call GotoXY
- mov si,offset ScreenBuffer
- add si,di
- mov cl,NumColum
- or cl,cl ; comprobar numero de columnas nulo
- jz Continue
-
- NextCaracter: lodsb ; cargar caracter
- inc si ; ignorar el atributo
- cmp al,20h ; comprobar caracteres de control
- jae CaracterOk
- mov al,20h ; filtrar caracteres de control
- CaracterOk: mov byte ptr es:[di],al ; dibujar rastro de impresión
- inc di
- mov byte ptr es:[di],78h
- inc di
- xor ah,ah ; enviar caracter a impresora
- xor dx,dx
- int 17h
- loop NextCaracter ; procesar siguiente caracter
-
- Continue: mov ax,000dh ; imprimir el par CR-LF
- xor dx,dx
- int 17h
- mov ax,000ah
- xor dx,dx
- int 17h
- inc CurrentLine ; actualizar linea actual
- pop cx
- loop NextLine ; siguiente linea por favor ...
-
- PrintExit: pop es
- ret
- PrintCode endp
-
- ScreenSeg dw 0B800h ; segmento inicial del segmento de pantalla
- ScreenFSeg dw 0B800h ; segmento final del buffer de pantalla
- State db 0 ; ¿ estoy ya en pantalla ?
- Recursive db 0 ; ¿ estoy en modo recursivo ?
- xCoord db 26d ; coordenadas de la ventana
- yCoord db 8d
- x1Coord db 52d
- y1Coord db 16d
- LastVector dd 0 ; vector 05h anterior
- NumColum db 0 ; numero de columnas a imprimir
- CurrentLine db 0 ; linea de impresión actual
- ScreenBuffer db 0 ; el buffer se crea 'al vuelo'
-
- Start proc near ; el atributo NEAR es irrelevante
- cld
- mov ax,Title0L ; visualizar titulos
- mov si,offset Title0
- call ScreenCenter
- mov ax,Title1L
- mov si,offset Title1
- call ScreenCenter
- call ScreenCR
- push ds
- xor ax,ax ; AX=0000h
- mov ds,ax
- lds si,ds:[0014h] ; [DS:SI] vector de interrupción 05h
- mov di,offset PrtScrVector
- mov cx,0ah ; 10 palabras iguales es mucha casualidad
- repz cmpsw
- jz AlreadyInst
- mov ds,ax ; AX=0000h
- mov si,0014h ; salvar vector 05h anterior
- mov di,offset LastVector
- movsw
- movsw
- pop ds
- push es
- mov es,ax ; AX todavía es 0000h
- mov di,0014h
- mov ax,offset PrtScrVector
- stosw ; colocar OFFSET
- mov ax,cs
- stosw ; colocar SEGMENT
- pop es
- int 11h ; obtener configuración del sistema
- and ax,0030h ; aislar campo -> tipo de video
- cmp ax,0030h ; comprobar si es adaptador mono
- jnz ColorAdapted
- mov ScreenSeg,0B000h ; segmento para adaptador mono
- ColorAdapted: mov si,offset InstallTxt
- call ScreenPrint
- call ScreenCR
- mov dx,offset ScreenBuffer+ScreenLenght
- int 27h ; DOS TSR
- AlreadyInst: pop ds ; recuperar DS
- mov si,offset NoInstallTxt
- call ScreenPrint ; visualizar texto de no instalar
- call ScreenCR
- int 20h ; pasar el control al DOS
- Start endp
-
- ScreenPrint proc near ; visualiza texto hasta encontrar NULL
- lodsb
- or al,al
- jz EndPrint
- mov ah,0eh
- xor bx,bx
- int 10h ; BIOS TTY
- jmp ScreenPrint
- EndPrint: ret
- ScreenPrint endp
-
- ScreenCenter proc near ; visualiza texto centrado
- mov cx,ax
- CenterPad: mov ax,0e20h
- xor bx,bx
- int 10h
- loop CenterPad
- call ScreenPrint
- call ScreenCR
- ret
- ScreenCenter endp
-
- ScreenCR proc near ; visualiza el par CR-LF
- mov ax,0e0dh
- xor bx,bx
- int 10h
- mov ax,0e0ah
- xor bx,bx
- int 10h
- ret
- ScreenCR endp
-
- Title0 db 'Print Screen V1.0 Impresión selectiva de pantalla',0d
- Title0L equ (80-($-Title0-1))/2
- Title1 db 'por Aitor Garay',0d
- Title1L equ (80-($-Title1-1))/2
- InstallTxt db 'Print Screen acaba de ser instalado.',0d
- NoInstallTxt db 'Print Screen ya ha sido instalado anteriormente.',0d
-
- code ends
- end Init